vfs: check userland buffers before reading them.
[haiku.git] / src / apps / haiku3d / RenderView.cpp
blob6773590a07bb83f8489f69a1d70da295d15290e4
1 /*
2 * Copyright 2008, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Alexandre Deckner <alex@zappotek.com>
7 */
9 #include "RenderView.h"
11 #include "BitmapTexture.h"
12 #include "Camera.h"
13 #include "MeshInstance.h"
14 #include "StaticMesh.h"
15 #include "VideoFileTexture.h"
17 #include <GL/gl.h>
18 #include <GL/glu.h>
20 #include <TranslationKit.h>
21 #include <TranslationUtils.h>
23 #include <stdio.h>
25 RenderView::RenderView(BRect frame)
27 BGLView(frame, "renderView", B_FOLLOW_ALL, B_WILL_DRAW,
28 BGL_RGB | BGL_DOUBLE | BGL_DEPTH),
29 fMainCamera(NULL),
30 fRenderThread(-1),
31 fStopRendering(false),
32 fRes(0, 0),
33 fNextRes(0, 0),
34 fLastFrameTime(0)
39 RenderView::~RenderView()
41 _StopRenderThread();
42 _DeleteScene();
46 void
47 RenderView::AttachedToWindow()
49 BGLView::AttachedToWindow();
51 _CreateScene();
52 _InitGL();
53 if (_CreateRenderThread() != B_OK)
54 printf("Error trying to start the render thread!\n");
58 uint32
59 RenderView::_CreateRenderThread()
61 fRenderThread = spawn_thread(RenderView::_RenderThreadEntry, "renderThread",
62 B_NORMAL_PRIORITY, this);
64 if (fRenderThread < 0)
65 return fRenderThread;
67 return resume_thread(fRenderThread);
71 void
72 RenderView::_StopRenderThread()
74 LockGL();
75 fStopRendering = true;
76 UnlockGL();
78 if (fRenderThread >= 0)
79 wait_for_thread(fRenderThread, NULL);
83 int32
84 RenderView::_RenderThreadEntry(void* pointer)
86 return reinterpret_cast<RenderView*>(pointer)->_RenderLoop();
90 int32
91 RenderView::_RenderLoop()
93 fLastFrameTime = system_time();
95 while (_Render()) {
96 snooze(10000);
98 return B_OK;
102 void RenderView::_InitGL(void)
104 LockGL();
106 float position[] = {0.0, 3.0, 6.0, 0.0};
107 float local_view[] = {0.0, 0.0};
109 glLightfv(GL_LIGHT0, GL_POSITION, position);
110 glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
112 float white[3] = {1.0, 1.0, 1.0};
114 glEnable(GL_LIGHT0);
115 glLightfv(GL_LIGHT0, GL_SPECULAR, white);
116 glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
117 glLightfv(GL_LIGHT0, GL_AMBIENT, white);
119 glMaterialf(GL_FRONT, GL_SHININESS, 0.6 * 128.0);
121 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
122 glEnable(GL_CULL_FACE);
123 glEnable(GL_DEPTH_TEST);
124 glEnable(GL_LIGHTING);
125 glEnable(GL_TEXTURE_2D);
127 fNextRes.Set(Bounds().Width(), Bounds().Height());
128 _UpdateViewport();
130 UnlockGL();
134 void
135 RenderView::_CreateScene()
137 Texture* texture = new BitmapTexture(
138 BTranslationUtils::GetBitmap(B_PNG_FORMAT, "texture"));
140 float spacing = 1.6f;
141 float timeSpacing = 5.0f;
142 float yOffset = -1.0f;
143 float zOffset = -16;
145 Mesh* mesh = new StaticMesh("LetterH");
146 MeshInstance* instance = new MeshInstance(mesh, texture,
147 Vector3(-3.6 * spacing, yOffset, zOffset),
148 Quaternion(0, 0, 0, 1), 0.0f);
149 fMeshInstances.push_back(instance);
150 mesh->ReleaseReference();
152 mesh = new StaticMesh("LetterA");
153 instance = new MeshInstance(mesh, texture,
154 Vector3(-1.6 * spacing, yOffset, zOffset),
155 Quaternion(0, 0, 0, 1), 1.0f * timeSpacing);
156 fMeshInstances.push_back(instance);
157 mesh->ReleaseReference();
159 mesh = new StaticMesh("LetterI");
160 instance = new MeshInstance(mesh, texture,
161 Vector3(0 * spacing, yOffset, zOffset),
162 Quaternion(0, 0, 0, 1), 2.0f * timeSpacing);
163 fMeshInstances.push_back(instance);
164 mesh->ReleaseReference();
166 mesh = new StaticMesh("LetterK");
167 instance = new MeshInstance(mesh, texture,
168 Vector3(1.5 * spacing, yOffset, zOffset),
169 Quaternion(0, 0, 0, 1), 3.0f * timeSpacing);
170 fMeshInstances.push_back(instance);
171 mesh->ReleaseReference();
173 mesh = new StaticMesh("LetterU");
174 instance = new MeshInstance(mesh, texture,
175 Vector3(3.4 * spacing, yOffset, zOffset),
176 Quaternion(0, 0, 0, 1), 4.0f * timeSpacing);
177 fMeshInstances.push_back(instance);
178 mesh->ReleaseReference();
179 texture->ReleaseReference();
181 fMainCamera = new Camera(Vector3(0, 0, 0), Quaternion(0, 0, 0, 1), 50);
185 void
186 RenderView::_DeleteScene()
188 MeshInstanceList::iterator it = fMeshInstances.begin();
189 for (; it != fMeshInstances.end(); it++) {
190 delete (*it);
192 fMeshInstances.clear();
196 void
197 RenderView::_UpdateViewport()
199 if (fNextRes != fRes && fNextRes.x >= 1.0 && fNextRes.y >= 1.0) {
200 glViewport(0, 0, (GLint) fNextRes.x + 1, (GLint) fNextRes.y + 1);
201 fRes = fNextRes;
202 _UpdateCamera();
207 void
208 RenderView::_UpdateCamera()
210 // TODO: take camera orientation into account
211 glMatrixMode(GL_PROJECTION);
212 glLoadIdentity();
213 gluPerspective(fMainCamera->FieldOfView(), fNextRes.x / fNextRes.y,
214 fMainCamera->Near(), fMainCamera->Far());
215 glMatrixMode(GL_MODELVIEW);
219 bool
220 RenderView::_Render()
222 LockGL();
224 _UpdateViewport();
226 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
227 glLoadIdentity();
229 bigtime_t time = system_time();
230 float deltaTime = 0.000001 * (float)(time - fLastFrameTime);
231 fLastFrameTime = time;
233 MeshInstanceList::iterator it = fMeshInstances.begin();
234 for (; it != fMeshInstances.end(); it++) {
235 (*it)->Update(deltaTime);
236 (*it)->Render();
239 if (fStopRendering) {
240 UnlockGL();
241 return false;
243 UnlockGL();
244 SwapBuffers(false); // true = vsync
245 return true;
249 void
250 RenderView::FrameResized(float width, float height)
252 LockGL();
253 fNextRes.Set(width, height);
254 UnlockGL();
255 BGLView::FrameResized(width, height);
259 void
260 RenderView::ErrorCallback(unsigned long error)
262 fprintf(stderr, "OpenGL error (%lu): %s\n", error, gluErrorString(error));